<template>
  <div class="myapp w-full h-full ">
    <div class="main flex flex-row">
      <Sidebar class="sidebar-container ml-auto" />
      <div class="wrap h-full w-full">
        <div class="hd flex flex-row h-11 w-full items-center">
          <Hamburger :is-active="sidebar.opened" class="hamburger h-1/2" @toggle-click="toggleSidebar" />
          <Breadcrumb class="h-1/2 breadcrumb" />
        </div>
        <div class="mainSection">
          <!-- 列表 -->
          <div class="w-full h-full flex flex-row justify-center items-center overflow-y-scroll">
            <div class="formWrap w-[66%] h-full">
              <vxe-form class="w-full h-full rounded-3 !bg-white !justify-center items-center" :data="formData"
                :items="formItems" titleColon @submit="submitEvent" @reset="resetEvent" align="center">
                <template #buttonGroup="{ data }">
                  <vxe-button v-for="(btxt, i) in data.buttonGroup" :key="i" :content="btxt"
                    @click="buttonsEvent"></vxe-button>
                </template>
              </vxe-form>
            </div>
            <div class="netJSON overflow-y-scroll h-full flex-1 !bg-white mt-[110px] pb-[20px] rounded-3">
              <json-viewer class="rounded-3" expand-depth="2" v-if="formData!.netConfig"
                :value="JSON.parse(formData!.netConfig).layers" copyable sort :expand="true" />
            </div>
          </div>
          <vxe-modal v-model="modal1" width="1500" height="500" show-footer>
            <template #title>
              <span style="color: red">模型训练信息</span>
            </template>

            <template #default>
              <vxe-table class="w-full h-full" border @toggle-row-expand="" show-overflow height="100%"
                :sync-resize="modal1" :data="infoData">
                <vxe-column type="expand" width="80" :fixed="expandFixed">
                  <template #content="{ row, rowIndex }">
                    <div class="expand-wrapper">
                      <ul>
                        <li>
                          <span>描述：</span>
                          <span>{{ row.description }}</span>
                        </li>
                        <li>
                          <span>特征值:</span>
                          <span>{{ row.features }}</span>
                        </li>
                        <li>
                          <span>特征转换:</span>
                          <span>{{ row.scaler_type }}</span>
                        </li>
                        <li>
                          <span>训练层:</span>
                          <json-viewer expand-depth="2" :value="row.layers" copyable boxed sort :expand="true" />
                        </li>
                      </ul>
                    </div>
                  </template>
                </vxe-column>

                <vxe-column v-for="(key, index) in FIELD" :key="index" width="251" :field="key.field"
                  :title="key.title"></vxe-column>
              </vxe-table>
            </template>
          </vxe-modal>
          <vxe-modal v-model="modal2" @show="showRender" width="750" height="550" show-footer>
            <template #title>
              <span style="color: red">训练结果图</span>
            </template>
            <template #default>
              <div class="w-full h-full" ref="chartDom"></div>
            </template>
          </vxe-modal>
          <vxe-modal v-model="modal3" @show="showRender" width="1200" height="550" show-footer>
            <template #title>
              <span style="color: red">测试集结果</span>
            </template>
            <template #default>
              <vxe-toolbar ref="toolbarRef" custom>
                <template #tools>
                  <vxe-button type="text" icon="vxe-icon-download" class="tool-btn" @click="toolDownload"></vxe-button>
                </template>
              </vxe-toolbar>
              <vxe-table ref="tableRef" class="w-full h-full" border @toggle-row-expand="" show-overflow height="450"
                :sync-resize="modal1" :data="dataSetData">
                <vxe-column v-for="(item, keys) in dataSetKeys" :key="keys" width="251" :field="item"
                  :title="item"></vxe-column>
                <!-- <vxe-column field="焊速" title="焊速"></vxe-column>
                <vxe-column field="下压力" title="下压力"></vxe-column>
                <vxe-column field="屈服强度True" title="屈服强度True"></vxe-column>
                <vxe-column field="屈服强度Predict" title="屈服强度Predict"></vxe-column> -->
              </vxe-table>
            </template>
          </vxe-modal>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import modelTrainOption from "@/utils/echarts/modelTrain"
import { ref } from "vue"
import { storeToRefs } from "pinia"
import { useAppStore } from "@/store/modules/app"
import { Sidebar, Breadcrumb, Hamburger } from "@/layouts/components"
import dayjs from "dayjs"
import {
  VxeTableInstance,
  VxeToolbarInstance,
  VXETable,
  VxeFormPropTypes,
  VxeFormEvents,
  VxeButtonEvents,
  VxeColumnPropTypes
} from "vxe-table"
import { ElMessage } from "element-plus"
const FIELD = [
  { field: 'run_name', title: '训练名称' },
  { field: 'epochs', title: '最大迭代次数' },
  { field: 'optimizer', title: '优化器' },
  { field: 'learn_rate', title: '学习率' },
  { field: 'random_seed', title: '随机种子' },
  { field: 'loss_function', title: '损失函数' },
  { field: 'winitializer', title: '初始化函数' },
  { field: 'batch_size', title: '批大小' },
  { field: 'test_set_ratio', title: '测试集的比例' },
  { field: 'labels', title: '标签' },
  { field: 'use_l2', title: 'L2正则项的权重' },

]
interface FormDataVO {
  runId: string
  status: string
  startTime: string
  netConfig: string
  endTime: string
  duration: string
  description: string
  testLossList: number[]
  trainLossList: number[]
  lifecycleStage: string
  experimentId: string
  runName: string
  buttonGroup: string[]
  testResult: [],
  finalTrainLoss: number,
  finalTestLoss: number,
  "batch_size": "",
  "scaler_type": "",
  "optimizer": "",
  "winitializer": "",
  "test_set_ratio": "",
  "use_l2": "",
  "random_seed": "",
  "epochs": "",
  "learn_rate": "",
  "set_name": "",
  "loss_function": "",
}
let { proxy } = getCurrentInstance() as any
let modelTrainRefOption = ref(modelTrainOption)
const expandFixed = ref<VxeColumnPropTypes.Fixed>()
let modal1 = ref(false)
let infoData = ref([] as any)
let modal2 = ref(false)
let modal3 = ref(false)
let dataSetData = ref()
let dataSetKeys = ref<string[]>([])
let formData = reactive<FormDataVO>({
  runId: "",
  finalTestLoss: 0,
  finalTrainLoss: 0,
  status: "",
  startTime: "",
  netConfig: "",
  endTime: "",
  duration: "",
  description: "",
  "batch_size": "",
  "scaler_type": "",
  "optimizer": "",
  "winitializer": "",
  "test_set_ratio": "",
  "use_l2": "",
  "random_seed": "",
  "epochs": "",
  "learn_rate": "",
  "loss_function": "",
  "set_name": "",
  testLossList: [],
  trainLossList: [],
  lifecycleStage: "",
  experimentId: "",
  runName: "",
  buttonGroup: ["查看测试集结果", "查看训练结果", "下载损失结果"],
  testResult: [] as any
})

const route = useRoute()
let rowData = route!.query!.rowData!
let chartDom = ref()
const tableRef = ref<VxeTableInstance>()
const toolbarRef = ref<VxeToolbarInstance>()

const toolDownload = (e) => {
  //导出 csv
  tableRef.value!.exportData({
    filename: 'testSet',
    type: 'csv',
    data: dataSetData.value
  })
}

//弹窗的渲染函数，这里渲染图表
const showRender = () => {
  setTimeout(() => {
    if (chartDom.value) {
      let trainMainInstance = proxy!.$echarts.init(chartDom.value)
      // console.log(formData.testLossList, formData.trainLossList)
      modelTrainRefOption.value.series[1].data = JSON.parse(formData.testLossList as any)
      modelTrainRefOption.value.series[0].data = JSON.parse(formData.trainLossList as any)
      let t = [] as any;
      JSON.parse(formData.trainLossList as any).forEach((_, index: number) => {
        t.push(index + 1)
      })
      modelTrainRefOption.value.xAxis.data = t
      // proxy.trainMainInstance = trainMainInstance
      trainMainInstance && trainMainInstance.setOption(modelTrainRefOption.value)
    }
  }, 111)
}
const buttonsEvent: VxeButtonEvents.Click = (e) => {
  switch (e.$button.props.content) {
    case "查看训练结果":
      modal2.value = true
      break
    case "查看测试集结果":
      let newArray = [] as any
      let keys = [] as any
      let vals = [] as any
      formData.testResult.forEach((item: string, index) => {
        let arr = item.split("=");
        keys.push(arr[0])
        vals.push(arr[1])
      })
      dataSetKeys.value = keys;
      JSON.parse(vals[0]).forEach((val: any, i) => {
        let o = {} as any
        keys.forEach((key: any, ii) => {
          o[key] = JSON.parse(vals[ii])[i]
        })
        newArray.push(o)
      })
      dataSetData.value = newArray
      // console.log(dataSetData.value)
      modal3.value = true
      break
    case "下载损失结果":
      let url = "/ai/export-service/bpnnLossCsv"
      let params = {
        userId: "zbx",
        experimentId: "1",
        runId: formData.runId
      }
      proxy.$http.post(url, params).then((res: any) => {
        let data = res.data
        const a = document.createElement("a")
        const blob = new Blob([data])
        const href = window.URL.createObjectURL(blob)
        a.href = href
        let fileName = "loss.csv"
        a.download = fileName
        ElMessage.success("下载正在进行中，请稍后！")
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        window.URL.revokeObjectURL(href)
      })
      break
  }
}
//文档 https://vxeui.com/#/form/api?apiKey=form
const formItems = ref<VxeFormPropTypes.Items>([
  {
    align: "center",
    title: "左侧",
    span: 12,
    className: "forCenter",
    children: [
      { slots: { default: "buttonGroup" }, span: 24 },
      {
        field: "experimentId",
        title: "实验id",
        span: 12,
        itemRender: { name: "$input", props: { placeholder: "请选择", disabled: true } }
      },
      {
        field: "runId",
        title: "模型id",
        span: 12,
        itemRender: { name: "$input", props: { placeholder: "请输入", disabled: true } }
      },
      {
        field: "runName",
        title: "运行名称",
        span: 12,
        itemRender: { name: "$input", props: { placeholder: "请输入名称" } }
      },
      {
        field: "status",
        title: "状态",
        span: 12,
        itemRender: {
          name: "$input",
          props: { disabled: true },
          options: [
            { label: "爬山", value: "11" },
            { label: "健身", value: "22" }
          ]
        }
      },
      { field: "description", title: "描述", span: 24, itemRender: { name: "$textarea" } },
      { field: "set_id", title: "数据集id", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "new_file_name", title: "数据集名称", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "features", title: "特征字段列表(Features)", span: 24, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "labels", title: "目标字段列表(Labels)", span: 24, itemRender: { name: "$input", props: { disabled: true } }, },
      { field: "startTime", title: "开始时间", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "endTime", title: "结束时间", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "finalTrainLoss", title: "最终训练损失值", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "finalTestLoss", title: "最终测试损失值", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "epochs", title: "最大迭代次数", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "learn_rate", title: "学习率", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "loss_function", title: "损失函数", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "batch_size", title: "批大小", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "scaler_type", title: "特征转换", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "optimizer", title: "优化器", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "winitializer", title: "初始化函数", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "test_set_ratio", title: "测试集比例", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "use_l2", title: "L2正则项的权重", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      { field: "random_seed", title: "随机种子", span: 12, itemRender: { name: "$input", props: { disabled: true } } },
      {
        field: "duration",
        title: "持续时间",
        span: 12,
        itemRender: { name: "$input", props: { placeholder: "请输入", disabled: true } }
      },
      { field: "lifecycleStage", title: "周期状态", span: 12, itemRender: { name: "$input", props: { disabled: true } } },

      // 放在里面才有效
    ]
  },
  // {
  //   align: "center",
  //   span: 24,
  //   itemRender: {
  //     name: "$buttons",
  //     children: [{ props: { type: "submit", content: "保存修改", status: "primary" } }]
  //   }
  // }
])

const submitEvent: VxeFormEvents.Submit = (e) => {
  console.log(e)
  VXETable.modal.message({ content: "保存成功", status: "success" })
}

const appStore = useAppStore()
const { sidebar } = storeToRefs(appStore)

/** 切换侧边栏 */
const toggleSidebar = () => {
  appStore.toggleSidebar(false)
}
onMounted(() => {
  let row = JSON.parse(rowData as string) as unknown as FormDataVO
  Object.assign(formData, row)
  Object.assign(formData, JSON.parse(row.netConfig))
  formData.finalTestLoss = row.finalTestLoss
  formData.finalTrainLoss = row.finalTrainLoss
})

nextTick(() => {
  // 将表格和工具栏进行关联
  const $table = tableRef.value
  const $toolbar = toolbarRef.value
  if ($table && $toolbar) {
    $table.connect($toolbar)
  }
})
</script>

<style lang="scss" scoped>
$transition-time: 0.35s;

.main {
  width: 100%;
  height: 100%;
}

.wrap {
  .hd {
    width: 100%;

    .sidebar-container {
      transition: width $transition-time;
      width: var(--v3-sidebar-width) !important;
      height: 100%;
      position: fixed;
      top: 0;
      bottom: 0;
      left: 0;
      z-index: 1001;
      overflow: hidden;
    }

    .hamburger {
      display: flex;
      align-items: center;
      cursor: pointer;
    }

    .breadcrumb {
      float: left;
      line-height: 1.45rem !important;

      @media screen and (max-width: 576px) {
        display: none;
      }
    }
  }

  .mainSection {
    @apply w-full;
    height: calc(100% - 2.75rem);
  }

  .forCenter {
    justify-content: center;
    align-items: center;
  }

  :deep(.vxe-form .vxe-form--wrapper) {
    justify-content: center;
    align-items: center;
    margin: 55px;
  }
}
</style>
